package com.platform.modules.dd.service.impl;

import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponseBody;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.request.OapiV2UserGetbymobileRequest;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.JedisUtil;
import com.platform.common.utils.StringUtils;
import com.platform.modules.dd.service.IDingTalkNotification;
import com.platform.modules.sys.service.SysConfigService;
import com.taobao.api.ApiException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service("DingTalkNotification")
public class DingTalkNotificationImpl implements IDingTalkNotification {

    public final long AGENT_ID = 1376593406L;
    public final String APP_KEY = "ding1lgkkkictp7pxes8";
    public final String APP_SECRET = "ZX1wyoAsX5xDMb_Fx7zgwBXvTEd7DB8UVatFxHvj9z9FqzrQWJ-yzPtK4IOYpZnU";
    public final String TOKEN_CACHE_KEY = "DD:ACCESS_TOKEN";
    public final String USERID_CACHE_KEY = "DD:GROUP_USER_ID:";

    @Resource
    private JedisUtil jedisUtil;
    @Resource
    private SysConfigService configService;

    @Override
    public void sentWorkNotification(String groupKye, String title, String text) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
            OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
            req.setAgentId(AGENT_ID);
            req.setUseridList(getUserIdFromCache(groupKye));
            OapiMessageCorpconversationAsyncsendV2Request.Msg obj1 = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
            obj1.setMsgtype("markdown");
            OapiMessageCorpconversationAsyncsendV2Request.Markdown obj2 = new OapiMessageCorpconversationAsyncsendV2Request.Markdown();
            obj2.setText("**" + title + "**  \n  " + text);
            obj2.setTitle(title);
            obj1.setMarkdown(obj2);
            req.setMsg(obj1);
            OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(req, this.getTokenFromCache());
            System.out.println(rsp.getBody());
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("工作通知发送出错！");
        }
    }

    /**
     * 使用 Token 初始化账号Client
     *
     * @return Client
     * @throws Exception
     */
    private com.aliyun.dingtalkoauth2_1_0.Client createClient() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkoauth2_1_0.Client(config);
    }

    /**
     * 根据用户手机获取钉钉userId
     *
     * @return
     * @throws Exception
     */
    private String getByMobile(String mobile) throws Exception {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
            OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
            req.setMobile(mobile);
            OapiV2UserGetbymobileResponse rsp = client.execute(req, this.getTokenFromCache());
            if (rsp.getErrcode() != 0) {
                return null;
            }
            return rsp.getResult().getUserid();
        } catch (ApiException e) {
            e.printStackTrace();
            throw new BusinessException("获取用户ID时出错！");
        }
    }

    /**
     * 获取缓存中的token
     *
     * @return
     * @throws Exception
     */
    public String getUserIdFromCache(String groupKye) throws Exception {
        String userIds = jedisUtil.get(USERID_CACHE_KEY + groupKye);
        if (StringUtils.isBlank(userIds)) {
            StringBuilder tempUserIds = new StringBuilder();
            for (String str : configService.getValue(groupKye, "").split(",")) {
                String userid = this.getByMobile(str);
                if (userid != null) {
                    tempUserIds.append(userid).append(",");
                }
            }
            if (StringUtils.isBlank(tempUserIds.toString().trim())) {
                throw new BusinessException("未查询到任何用户ID");
            }
            tempUserIds.setLength(tempUserIds.length() - 1);
            userIds = tempUserIds.toString();
            jedisUtil.set(USERID_CACHE_KEY + groupKye, userIds, 86400);
        }
        return userIds;
    }

    /**
     * 获取缓存中的token
     *
     * @return
     * @throws Exception
     */
    public String getTokenFromCache() throws Exception {
        String token = jedisUtil.get(TOKEN_CACHE_KEY);
        if (StringUtils.isBlank(token)) {
            GetAccessTokenResponseBody responseBody = this.getToken();
            token = responseBody.accessToken;
            jedisUtil.set(TOKEN_CACHE_KEY, token, responseBody.getExpireIn().intValue());
        }
        return token;
    }

    /**
     * 获取token
     *
     * @return
     * @throws Exception
     */
    private GetAccessTokenResponseBody getToken() throws Exception {
        com.aliyun.dingtalkoauth2_1_0.Client client = this.createClient();
        GetAccessTokenRequest getAccessTokenRequest = new GetAccessTokenRequest()
                .setAppKey(APP_KEY)
                .setAppSecret(APP_SECRET);
        try {
            return client.getAccessToken(getAccessTokenRequest).getBody();
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                throw new BusinessException("请求钉钉接口时出错：code:" + err.code + "\tmsg:" + err.message);
            }
            throw new BusinessException("请求钉钉接口时出错");
        }
    }
}
